Skip to content

feat: NanoBanana Pro 2 support (#320)#321

Open
tombeckenham wants to merge 6 commits intoTanStack:mainfrom
tombeckenham:320-nanobanana-pro-2-support
Open

feat: NanoBanana Pro 2 support (#320)#321
tombeckenham wants to merge 6 commits intoTanStack:mainfrom
tombeckenham:320-nanobanana-pro-2-support

Conversation

@tombeckenham
Copy link
Contributor

@tombeckenham tombeckenham commented Feb 27, 2026

Closes #320

Summary

Adds support for Google's NanoBanana (Gemini native image generation) models, including the new Gemini 3.1 Pro model.

NanoBanana Native Image Generation

  • Route all gemini-* image models through the generateContent API instead of only gemini-3.1-flash-image-preview
  • Fix incorrect SDK property names (imageGenerationConfigimageConfig, outputImageSizeimageSize)
  • Trim type values to match SDK expectations
  • Rename internal NanoBanana types to GeminiNativeImage for clarity
  • Bump @google/genai to ^1.43.0 for ImageConfig type support
  • Support NanoBanana size format (aspectRatio_resolution) distinct from Imagen sizing

Gemini 3.1 Pro Model

  • Add gemini-3.1-pro-preview model metadata (1M input tokens, 64K output tokens, pricing)
  • Register in GEMINI_MODELS list and type maps (provider options, input modalities)
  • Full capability support: thinking, structured output, function calling, search grounding, caching, and more

Documentation & Examples

  • Add documentation for NanoBanana native image models with size format, model tables, and usage examples
  • Rename example app from ts-react-fal to ts-react-media to reflect multi-provider support
  • Add Gemini image models to the example app alongside fal.ai models

Test plan

  • Verify pnpm test:types passes with new model types
  • Verify pnpm test:lib passes for ai-gemini package
  • Verify pnpm test:build succeeds

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Gemini 3.1 Pro and Gemini 3.1 Flash Image models; native Gemini (NanoBanana) image generation now supported up to 4K and unified with Imagen flows.
  • Documentation

    • Updated docs and guides with new model parameters, routing behavior, size formats, examples, and API reference updates.
  • Examples

    • Example app renamed to ts-react-media; added GOOGLE_API_KEY placeholder, header text update, improved image selector grouping and rendering.
  • Tests

    • Expanded image-adapter tests and added size-parsing tests.
  • Chores

    • Bumped Gemini package dependency.

tombeckenham and others added 3 commits February 27, 2026 16:00
Route all gemini-* image models through generateContent instead of only
gemini-3.1-flash-image-preview. Fix incorrect SDK property names
(imageGenerationConfig→imageConfig, outputImageSize→imageSize), trim
type values to match SDK, rename NanoBanana types to GeminiNativeImage,
and bump @google/genai to ^1.43.0 for ImageConfig type support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mage models

Add documentation for Gemini native image models (NanoBanana) that use
the generateContent API, including size format (aspectRatio_resolution),
model tables, and examples. Rename example app from ts-react-fal to
ts-react-media to reflect multi-provider support. Add Gemini image models
to the example app alongside fal.ai models.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tombeckenham tombeckenham requested a review from a team February 27, 2026 07:19
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

📝 Walkthrough

Walkthrough

Adds Gemini native image generation (generateContent) alongside existing Imagen generateImages path, introduces Gemini 3.1 models and native image sizing types, updates docs/examples to ts-react-media, and adapts examples and tests to support multi-provider image flows and new size formats.

Changes

Cohort / File(s) Summary
Documentation
docs/adapters/fal.md, docs/adapters/gemini.md, docs/guides/image-generation.md
Updated example app references to ts-react-media; documented geminiImage signature and dual routing (Gemini native → generateContent, Imagen → generateImages); added image size option guidance and model lists.
Example app & UI
examples/ts-react-media/package.json, examples/ts-react-media/.env.example, examples/ts-react-media/src/components/Header.tsx, examples/ts-react-media/src/routes/index.tsx
Renamed project to ts-react-media, added GOOGLE_API_KEY placeholder and @tanstack/ai-gemini workspace dep, and adjusted UI text to remove fal.ai branding.
Example app logic
examples/ts-react-media/src/lib/models.ts, examples/ts-react-media/src/components/ImageGenerator.tsx, examples/ts-react-media/src/lib/server-functions.ts
Added provider on image model entries and new Gemini/Imagen model entries; split model lists into falModels/geminiModels; added getImageSrc to normalize url/base64; added server-side cases using geminiImage(...) for Gemini native and Imagen models.
Adapter implementation
packages/typescript/ai-gemini/src/adapters/image.ts
Branched image flow: detect Gemini-native models and call generateContent via new generateWithGeminiApi; kept Imagen path using generateImages; added response transforms for each path and size parsing.
Types & sizing
packages/typescript/ai-gemini/src/image/image-provider-options.ts
Added GeminiNativeImage types (aspect ratios, resolutions, size union), updated GeminiImageModelSizeByName to discriminate native vs Imagen models, and exported parseNativeImageSize() helper.
Model metadata
packages/typescript/ai-gemini/src/model-meta.ts
Added GEMINI_3_1_PRO and GEMINI_3_1_FLASH_IMAGE model constants; extended GEMINI_MODELS and GEMINI_IMAGE_MODELS and related provider/option typings.
Deps & tests
packages/typescript/ai-gemini/package.json, packages/typescript/ai-gemini/tests/image-adapter.test.ts
Bumped @google/genai to ^1.43.0; expanded tests to cover parseNativeImageSize, generateContent payloads/responses, multi-image prompts, and edge cases.
Changelog
.changeset/five-parts-leave.md
Added changeset noting NanoBanana/Gemini native routing, SDK property fixes/renames (imageConfig/imageSize), and Gemini 3.1 Pro additions.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Adapter as GeminiImageAdapter
  participant SDK as `@google/genai`

  Client->>Adapter: generateImage(model, options)
  Adapter->>Adapter: isGeminiImageModel(model)?
  alt Gemini native model
    Adapter->>SDK: generateContent({ model, contents, imageConfig?, responseModalities: ['IMAGE'] })
    SDK-->>Adapter: GenerateContentResponse (inlineData / image parts)
    Adapter->>Client: ImageGenerationResult (map inlineData → images)
  else Imagen model
    Adapter->>SDK: generateImages({ model, prompt, size?, n })
    SDK-->>Adapter: GenerateImagesResponse (url/base64 images)
    Adapter->>Client: ImageGenerationResult (map images → result)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • jherr
  • AlemTuzlak

Poem

🐰 I hopped through code and payload streams,
Gemini paints and Imagen dreams,
NanoBanana, pixels bright,
Sizes parsed and models right,
A joyful rabbit taps “merge” tonight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: NanoBanana Pro 2 support (#320)' clearly summarizes the main change: adding support for NanoBanana native image models and Gemini 3.1 Pro, which is the primary objective of this PR.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all key changes: NanoBanana native image generation, Gemini 3.1 Pro model support, documentation updates, and example app renaming.
Linked Issues check ✅ Passed The PR fully addresses issue #320 requirements: routes all gemini-* models through generateContent, fixes property names (imageGenerationConfig→imageConfig, outputImageSize→imageSize), restricts types to SDK-supported values, renames types to GeminiNativeImage*, and bumps @google/genai to ^1.43.0.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: NanoBanana support, Gemini 3.1 Pro model addition, and example app updates. No unrelated functionality has been introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Feb 27, 2026

View your CI Pipeline Execution ↗ for commit c75e958

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 3m 32s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 42s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-27 11:05:39 UTC

@tombeckenham tombeckenham changed the title feat: add Gemini 3.1 Pro model support feat: NanoBanana Pro 2 support (#320) Feb 27, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 27, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@321

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@321

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@321

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@321

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@321

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@321

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@321

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@321

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@321

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@321

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@321

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@321

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@321

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@321

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@321

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@321

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@321

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@321

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@321

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@321

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@321

commit: 8597641

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/typescript/ai-gemini/src/image/image-provider-options.ts (2)

283-288: parseNativeImageSize does not validate resolution against allowed values.

The regex ^(\d+:\d+)_(.+)$ accepts any string after the underscore (e.g., "16:9_invalid" would parse successfully). Consider validating that the resolution matches GeminiNativeImageResolution ('1K' | '2K' | '4K').

🛡️ Suggested fix to validate resolution
+const VALID_NATIVE_RESOLUTIONS = ['1K', '2K', '4K'] as const
+
 export function parseNativeImageSize(
   size: string,
 ): { aspectRatio: string; resolution: string } | undefined {
-  const match = size.match(/^(\d+:\d+)_(.+)$/)
+  const match = size.match(/^(\d+:\d+)_(1K|2K|4K)$/)
   if (!match) return undefined
   return { aspectRatio: match[1]!, resolution: match[2]! }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-gemini/src/image/image-provider-options.ts` around
lines 283 - 288, parseNativeImageSize currently accepts any string after the
underscore (regex /^(\d+:\d+)_(.+)$/) so inputs like "16:9_invalid" are treated
as valid; update parseNativeImageSize to validate that the extracted resolution
equals one of the allowed GeminiNativeImageResolution values ('1K' | '2K' |
'4K') and return undefined for non-matching resolutions. Locate
parseNativeImageSize and after extracting match[2] check it against the
GeminiNativeImageResolution union (or a small set/array of allowed values) and
only return { aspectRatio: match[1], resolution: match[2] } when it matches;
otherwise return undefined.

177-182: Derive GeminiNativeImageModels from model metadata to prevent drift.

GeminiNativeImageModels is a hardcoded string union type while GeminiImageModels is derived from GEMINI_IMAGE_MODELS in model-meta.ts. If native image models are added or removed from the metadata, this type will not automatically update, leading to potential type mismatches in GeminiImageModelSizeByName. Consider extracting native models from the metadata structure (e.g., by filtering models with image_generation capability in their native implementation) to maintain synchronization.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-gemini/src/image/image-provider-options.ts` around
lines 177 - 182, Replace the hardcoded GeminiNativeImageModels union with a
derived type that filters GEMINI_IMAGE_MODELS for models whose native
implementation supports image generation: import GEMINI_IMAGE_MODELS from
model-meta.ts, compute the string literal union by filtering entries where
model.native?.capabilities (or equivalent) includes "image_generation" (or
checks native implementation), and export that inferred type to replace
GeminiNativeImageModels; update any usages such as GeminiImageModelSizeByName to
reference the new derived type so the set of native image models stays in sync
with the metadata.
docs/guides/image-generation.md (1)

175-185: Consider adding meaningful modelOptions example for Gemini native models.

The section is titled "Gemini Native Model Options (NanoBanana)" but the code example only shows size without any actual modelOptions. If native models support additional configuration, consider demonstrating it. Otherwise, clarify that native models primarily use the size parameter.

📝 Suggested documentation improvement
 ### Gemini Native Model Options (NanoBanana)
 
-Gemini native image models accept `GenerateContentConfig` options directly in `modelOptions`:
+Gemini native image models primarily use the `size` parameter for configuration. Additional `GenerateContentConfig` options can be passed via `modelOptions` if needed:
 
 ```typescript
 const result = await generateImage({
   adapter: geminiImage('gemini-3.1-flash-image-preview'),
   prompt: 'A beautiful garden',
   size: '16:9_4K',
+  // modelOptions are optional for native models
 })
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/guides/image-generation.md around lines 175 - 185, The example under
"Gemini Native Model Options (NanoBanana)" shows only size and omits
modelOptions; update the generateImage example (the call to generateImage and
adapter geminiImage('gemini-3.1-flash-image-preview')) to either include a
representative modelOptions object showing supported GenerateContentConfig
fields for native Gemini models (e.g., any rate/quality/seed-like options the
model accepts) or add a brief clarifying sentence stating that native models
only use size and modelOptions is optional; reference generateImage,
geminiImage, modelOptions, size, and GenerateContentConfig when making the
change so readers can find and understand the example.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @packages/typescript/ai-gemini/src/adapters/image.ts:

  • Around line 111-140: generateWithGeminiApi currently ignores the
    numberOfImages option so callers passing numberOfImages > 1 silently get one
    image; update generateWithGeminiApi (and its JSDoc) to either validate and throw
    when options.numberOfImages > 1 for Gemini native models, or map the intent to
    the Gemini API by setting candidateCount when supported (e.g., pass
    candidateCount = numberOfImages to this.client.models.generateContent), and
    ensure any thrown error or limitation is described in the method JSDoc and
    surfaced before calling this.client.models.generateContent; update
    transformGeminiResponse handling if you choose candidateCount so it returns
    multiple ImageGenerationResult entries accordingly.

Nitpick comments:
In @docs/guides/image-generation.md:

  • Around line 175-185: The example under "Gemini Native Model Options
    (NanoBanana)" shows only size and omits modelOptions; update the generateImage
    example (the call to generateImage and adapter
    geminiImage('gemini-3.1-flash-image-preview')) to either include a
    representative modelOptions object showing supported GenerateContentConfig
    fields for native Gemini models (e.g., any rate/quality/seed-like options the
    model accepts) or add a brief clarifying sentence stating that native models
    only use size and modelOptions is optional; reference generateImage,
    geminiImage, modelOptions, size, and GenerateContentConfig when making the
    change so readers can find and understand the example.

In @packages/typescript/ai-gemini/src/image/image-provider-options.ts:

  • Around line 283-288: parseNativeImageSize currently accepts any string after
    the underscore (regex /^(\d+:\d+)_(.+)$/) so inputs like "16:9_invalid" are
    treated as valid; update parseNativeImageSize to validate that the extracted
    resolution equals one of the allowed GeminiNativeImageResolution values ('1K' |
    '2K' | '4K') and return undefined for non-matching resolutions. Locate
    parseNativeImageSize and after extracting match[2] check it against the
    GeminiNativeImageResolution union (or a small set/array of allowed values) and
    only return { aspectRatio: match[1], resolution: match[2] } when it matches;
    otherwise return undefined.
  • Around line 177-182: Replace the hardcoded GeminiNativeImageModels union with
    a derived type that filters GEMINI_IMAGE_MODELS for models whose native
    implementation supports image generation: import GEMINI_IMAGE_MODELS from
    model-meta.ts, compute the string literal union by filtering entries where
    model.native?.capabilities (or equivalent) includes "image_generation" (or
    checks native implementation), and export that inferred type to replace
    GeminiNativeImageModels; update any usages such as GeminiImageModelSizeByName to
    reference the new derived type so the set of native image models stays in sync
    with the metadata.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 808c32d5cedcd6fa1f80387f1d03d8fc4481d3e1 and 2eaa47c426c71b7dc2c2bf9df4e46b1a77f00b98.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `pnpm-lock.yaml` is excluded by `!**/pnpm-lock.yaml`

</details>

<details>
<summary>📒 Files selected for processing (23)</summary>

* `docs/adapters/fal.md`
* `docs/adapters/gemini.md`
* `docs/guides/image-generation.md`
* `examples/ts-react-media/.env.example`
* `examples/ts-react-media/package.json`
* `examples/ts-react-media/src/components/Header.tsx`
* `examples/ts-react-media/src/components/ImageGenerator.tsx`
* `examples/ts-react-media/src/components/VideoGenerator.tsx`
* `examples/ts-react-media/src/lib/models.ts`
* `examples/ts-react-media/src/lib/prompts.ts`
* `examples/ts-react-media/src/lib/server-functions.ts`
* `examples/ts-react-media/src/routeTree.gen.ts`
* `examples/ts-react-media/src/router.tsx`
* `examples/ts-react-media/src/routes/__root.tsx`
* `examples/ts-react-media/src/routes/index.tsx`
* `examples/ts-react-media/src/styles.css`
* `examples/ts-react-media/tsconfig.json`
* `examples/ts-react-media/vite.config.ts`
* `packages/typescript/ai-gemini/package.json`
* `packages/typescript/ai-gemini/src/adapters/image.ts`
* `packages/typescript/ai-gemini/src/image/image-provider-options.ts`
* `packages/typescript/ai-gemini/src/model-meta.ts`
* `packages/typescript/ai-gemini/tests/image-adapter.test.ts`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/typescript/ai-gemini/src/adapters/image.ts (2)

42-55: Consider consistent naming in documentation.

The documentation refers to "Nano Banana 2" but the PR objectives and changeset use "NanoBanana" (without space). Consider standardizing the naming for consistency.

📝 Suggested fix
 * Tree-shakeable adapter for Gemini image generation functionality.
 * Supports Imagen 3/4 models (via generateImages API) and Gemini native
-* image models like Nano Banana 2 (via generateContent API).
+* image models like NanoBanana (via generateContent API).
 *
 * Features:
 * - Aspect ratio-based image sizing
 * - Person generation controls
 * - Safety filtering
 * - Watermark options
-* - Extended resolution tiers (Nano Banana 2)
+* - Extended resolution tiers (NanoBanana)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-gemini/src/adapters/image.ts` around lines 42 - 55,
The doc comment in the Gemini image adapter inconsistently uses "Nano Banana 2"
while the PR and changeset use "NanoBanana"; update the documentation string in
the image adapter (the top comment block in image.ts referencing "Nano Banana 2"
and any other occurrences like "Nano Banana") to the canonical "NanoBanana"
spelling used in the PR, ensuring any model mentions (e.g., references to
NanoBanana, NanoBanana 2 if versioned) and related phrases are consistently
renamed across this file and adjacent docs/comments so names match the
changeset.

81-105: Consider adding validation for Gemini native image sizes.

The Imagen path validates sizes via validateImageSize, but the Gemini path uses parseNativeImageSize which silently returns undefined for invalid formats. This means invalid size strings like "invalid" or "1024x1024" (Imagen format) passed to a Gemini model will be silently ignored rather than producing an error.

Consider adding validation for Gemini models to provide clearer feedback when an invalid size format is passed.

🛡️ Suggested validation approach
  private async generateWithGeminiApi(
    options: ImageGenerationOptions<GeminiImageProviderOptions>,
  ): Promise<ImageGenerationResult> {
    const { model, prompt, size, numberOfImages, modelOptions } = options

    const parsedSize = size ? parseNativeImageSize(size) : undefined
+   
+   // Validate size format for Gemini native models
+   if (size && !parsedSize) {
+     throw new Error(
+       `Invalid size format "${size}" for Gemini model. Expected format: "aspectRatio_resolution" (e.g., "16:9_4K")`
+     )
+   }

    // The generateContent API has no numberOfImages parameter.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-gemini/src/adapters/image.ts` around lines 81 - 105,
The Gemini path in generateImages currently skips size validation (when
isGeminiImageModel(model) is true) and parseNativeImageSize can return undefined
for invalid formats; update generateImages to validate Gemini native image sizes
before calling generateWithGeminiApi by calling
parseNativeImageSize(options.size) and if it returns undefined (or an
unsupported value) throw a descriptive validation error (or call a new helper
like validateNativeImageSize) so invalid strings (e.g., "invalid" or
Imagen-style "1024x1024") produce a clear error; modify generateImages (and/or
add validateNativeImageSize) to perform this check right before returning
generateWithGeminiApi.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/typescript/ai-gemini/src/adapters/image.ts`:
- Around line 157-161: The loop that pushes images uses part.inlineData.data
without guarding for undefined, causing b64Json to be set to undefined; update
the loop that iterates over parts (the variable parts and the part.inlineData
access) to only push when part.inlineData?.data is a non-empty string or buffer
(e.g., check typeof part.inlineData?.data === 'string' &&
part.inlineData.data.length > 0 or similar), and skip or handle cases where data
is missing so images.push({ b64Json: ... }) only occurs with valid data.

In `@packages/typescript/ai-gemini/tests/image-adapter.test.ts`:
- Line 286: Update the test description string for the test that currently reads
"calls generateContent without imageGenerationConfig when no size provided" to
use the renamed property name "imageConfig" instead of "imageGenerationConfig";
locate the it(...) block in image-adapter.test.ts that asserts generateContent
behavior (the test referencing generateContent) and change the human-readable
description to "calls generateContent without imageConfig when no size provided"
so the description matches the actual property name used in the code.

---

Nitpick comments:
In `@packages/typescript/ai-gemini/src/adapters/image.ts`:
- Around line 42-55: The doc comment in the Gemini image adapter inconsistently
uses "Nano Banana 2" while the PR and changeset use "NanoBanana"; update the
documentation string in the image adapter (the top comment block in image.ts
referencing "Nano Banana 2" and any other occurrences like "Nano Banana") to the
canonical "NanoBanana" spelling used in the PR, ensuring any model mentions
(e.g., references to NanoBanana, NanoBanana 2 if versioned) and related phrases
are consistently renamed across this file and adjacent docs/comments so names
match the changeset.
- Around line 81-105: The Gemini path in generateImages currently skips size
validation (when isGeminiImageModel(model) is true) and parseNativeImageSize can
return undefined for invalid formats; update generateImages to validate Gemini
native image sizes before calling generateWithGeminiApi by calling
parseNativeImageSize(options.size) and if it returns undefined (or an
unsupported value) throw a descriptive validation error (or call a new helper
like validateNativeImageSize) so invalid strings (e.g., "invalid" or
Imagen-style "1024x1024") produce a clear error; modify generateImages (and/or
add validateNativeImageSize) to perform this check right before returning
generateWithGeminiApi.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2eaa47c and 1e0e15d.

📒 Files selected for processing (3)
  • .changeset/five-parts-leave.md
  • packages/typescript/ai-gemini/src/adapters/image.ts
  • packages/typescript/ai-gemini/tests/image-adapter.test.ts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/typescript/ai-gemini/tests/image-adapter.test.ts (1)

229-517: Add explicit coverage for gemini-3.1-pro-preview in generateContent tests.

Current tests exercise only gemini-3.1-flash-image-preview. Since this PR adds support for all Gemini native image models (including pro), add a parameterized case so routing regressions are caught for both model IDs.

Example parameterized test pattern
+    it.each([
+      'gemini-3.1-flash-image-preview',
+      'gemini-3.1-pro-preview',
+    ] as const)('routes %s through generateContent', async (model) => {
+      const mockGenerateContent = vi.fn().mockResolvedValueOnce({
+        candidates: [{ content: { parts: [{ inlineData: { mimeType: 'image/png', data: 'img' } }] } }],
+      })
+
+      const adapter = createGeminiImage(model, 'test-api-key')
+      ;(adapter as unknown as { client: { models: { generateContent: unknown } } }).client = {
+        models: { generateContent: mockGenerateContent },
+      }
+
+      await adapter.generateImages({ model, prompt: 'A test prompt' })
+      expect(mockGenerateContent).toHaveBeenCalled()
+    })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-gemini/tests/image-adapter.test.ts` around lines 229 -
517, Add parameterized coverage for the pro image model by running the same
generateContent tests for both 'gemini-3.1-flash-image-preview' and
'gemini-3.1-pro-preview': refactor the repeated test blocks in
image-adapter.test.ts to iterate over an array of model IDs and for each call
createGeminiImage(modelId, 'test-api-key'), inject the mockGenerateContent into
adapter.client.models.generateContent, call adapter.generateImages(...) and
assert the same expectations (mockGenerateContent call shape, result.model,
result.images length and contents). Ensure tests that check prompt augmentation
(numberOfImages cases), imageConfig presence/absence, and empty responses are
all parameterized to include both model strings so routing for createGeminiImage
and adapter.generateImages is verified for the pro model as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/typescript/ai-gemini/tests/image-adapter.test.ts`:
- Around line 229-517: Add parameterized coverage for the pro image model by
running the same generateContent tests for both 'gemini-3.1-flash-image-preview'
and 'gemini-3.1-pro-preview': refactor the repeated test blocks in
image-adapter.test.ts to iterate over an array of model IDs and for each call
createGeminiImage(modelId, 'test-api-key'), inject the mockGenerateContent into
adapter.client.models.generateContent, call adapter.generateImages(...) and
assert the same expectations (mockGenerateContent call shape, result.model,
result.images length and contents). Ensure tests that check prompt augmentation
(numberOfImages cases), imageConfig presence/absence, and empty responses are
all parameterized to include both model strings so routing for createGeminiImage
and adapter.generateImages is verified for the pro model as well.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e0e15d and c75e958.

📒 Files selected for processing (2)
  • packages/typescript/ai-gemini/src/adapters/image.ts
  • packages/typescript/ai-gemini/tests/image-adapter.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/typescript/ai-gemini/src/adapters/image.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support all Gemini native image models (including 🍌)

1 participant